package awdc;

import java.util.concurrent.*;
import java.util.regex.*;

class Disp implements Runnable{
	Speaker Speak;
	ExecutorService Exec;
	ComWorker Worker;
	Hub ThisHub;
	NickList Nicks;
	Shara HShara;

	Disp(Speaker Speak, ExecutorService Exec, NickList Nicks, Shara HShara) {
		this.Nicks = Nicks;
		this.Speak = Speak;
		this.Exec = Exec;
		this.HShara = HShara;
	}

	public void run(){
		System.out.println("Disp started");
		byte[] buff=null;
		byte[] big = null;
		while (true) {
			System.out.println("One step of disp..");
			byte[] received = Speak.receive();
			System.out.println("Size of received at this step: " + received.length);
			if (received.length == 0) 
				buff = null;
			else {
				if (buff != null)
					System.out.println("Size of buff at this step: " + buff.length);
				else
					System.out.println("Size of buff at this step: buff IS NULL");
				String RecStr=null;
				try {
					RecStr = new String (received,"windows-1251");
				} catch (Exception e) {
					e.printStackTrace();
				}
				System.out.println("Sravnivaem:");
				if (Pattern.matches(".*\\|",RecStr)){
					System.out.println("matches!!");
					if (buff != null) {
						System.out.println("Buff is not null");
						big = new  byte[received.length + buff.length];
						for (int j=0;j<buff.length;j++)
							big[j]=buff[j];
						for (int j=buff.length;j<buff.length;j++)
							big[j]=received[j-buff.length];
						received = big;
						big = null;
					}
					try {
						RecStr = new String(received, "windows-1251");
						System.out.println("So we have: " + RecStr);
					} catch (Exception e) 
					{};
					Command CommandList = this.parseCommand(received);
					Command Temp = CommandList;
					while (Temp != null){
						Exec.execute(new ComWorker(Temp, Nicks, Speak, HShara));
						Temp = Temp.Next;
					}
				} else {
					System.out.println("Need to add next part of command");
					buff = new byte[received.length];
					for (int i=0;i<received.length;i++)
						buff[i]=received[i];
				}
			}


		}
	}

	//Метод, который распарсивает комманды, возвращая указатель на список из них
	Command parseCommand(byte[] Inline){
		Command FirstCommand = null;
		Command Temp = FirstCommand;
		Command Hlp=null;
		String InlineAsStr = null;
		try {
			InlineAsStr = new String (Inline,"windows-1251");
		} catch (Exception e) {
			e.printStackTrace();
		}

		Pattern ComPattern=null;
		try {
			ComPattern = Pattern.compile("(\\$[a-zA-Z]+|<[\\sa-zA-Z]+>)(\\s((.*?)\\|)|\\|)(.*)");
		} catch (Exception e) {
			e.printStackTrace();
		}

		int flag=0;
		while (InlineAsStr!=null){
			Matcher m = ComPattern.matcher(InlineAsStr);
			if (m.matches()) {
				InlineAsStr=m.group(5);
				if (FirstCommand==null) {
					FirstCommand = new Command(m.group(1),m.group(4));
					Temp = FirstCommand;
				} else {
					Temp.Next = new Command(m.group(1),m.group(4));
					Temp = Temp.Next;
				}

			} else 
				InlineAsStr = null;
		}
		return FirstCommand;
	}

	//Метод, выводящий список команд
	void showCommands(Command First){
		System.out.println("Commands:");
		if (First!=null){
			System.out.println(First.CommandName);
			First.showParams(First.Params);
			showCommands(First.Next);
		}
	}

	

}
